#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
    File Name:      wxpy_utils
    Author:         'daze'
    date:           2018/12/14
    参考文档：https://wxpy.readthedocs.io/
"""
# 导入模块
import wxpy
from wxpy import *
from wxpy.api import bot

from AutoWool.main.base.Singleton import Singleton


# 注意：尽量拿小号测试，否则微信网页版可能会被限制登录
# 获取 bot 实例直接使用 bot_instance
class WxPyUtils(Singleton):
    # 初始化机器人，扫码登陆，如果需要微信多开则初始化多个 Bot 对象并添加到 self.bot_list 中
    # cache_path 表示开启缓存功能，可在短时间内避免重复扫码，缓存失效时会重新要求登陆，为 True 时使用默认的缓存路径 ‘wxpy.pkl’
    # console_qr 在终端中显示登陆二维码，需要安装 pillow 模块
    bot_list = [Bot(cache_path=True, console_qr=False)]
    bot_instance = bot_list[0]  # 默认就添加一个

    # 启用 puid 属性，并指定 puid 所需的映射数据保存/载入路径，puid 是 wxpy 特有的聊天对象/用户ID，可始终被获取到，且具有稳定的唯一性
    # bot.enable_puid('wxpy_puid.pkl')
    # 为 True 时，将自动消除手机端的新消息小红点提醒 (默认为 False)
    # Bot.auto_mark_as_read = True

    # 堵塞进程，直到结束消息监听 (例如，机器人被登出时)
    @staticmethod
    def bot_join():
        WxPyUtils.bot_instance.join()

    # 登出
    @staticmethod
    def logout():
        WxPyUtils.bot_instance.logout()

    """ __________搜索__________"""

    # 获取所有朋友
    @staticmethod
    def get_all_friends():
        return WxPyUtils.bot_instance.friends()

    # 根据朋友名称找到指定朋友
    @staticmethod
    def find_friend(friend_name, ensure_one_param=True, **attributes):
        # .search('游否', sex=MALE, city="深圳")[0]
        result_list = WxPyUtils.bot_instance.friends().search(friend_name, **attributes)
        if ensure_one_param:
            return ensure_one(result_list)
        return result_list

    # 获取所有群聊对象（一些不活跃的群可能无法被获取到，可通过在群内发言，或修改群名称的方式来激活）
    @staticmethod
    def get_all_groups():
        return WxPyUtils.bot_instance.groups()

    # 搜索群聊
    @staticmethod
    def search_group(group_name, *users, **attributes):
        WxPyUtils.get_all_groups().search(group_name, users, **attributes)  # 搜索名称包含group_name，且成员中包含 obj_name 的群聊对象

    # 获取所有公众号
    @staticmethod
    def get_all_public_addrs():
        return WxPyUtils.bot_instance.mps()

    # 获取所有聊天对象
    @staticmethod
    def get_all_chats():
        return WxPyUtils.bot_instance.chats()

    # 搜索任意类型对象
    @staticmethod
    def get_arbitrarily_obj(keywords=None, **attributes):
        # [<Friend: wxpy 机器人>, <Group: wxpy 交流群 1>, <Group: wxpy 交流群 2>]
        WxPyUtils.bot_instance.search(keywords, **attributes)

    # 获取单个或批量获取多个用户的详细信息(地区、性别、签名等)，但不可用于群聊成员
    # user_or_users – 单个或多个用户对象或 user_name
    # chunk_size – 分配请求时的单批数量，目前为 50
    @staticmethod
    def get_user_details(user_or_users, chunk_size=50):
        return WxPyUtils.bot_instance.user_details(user_or_users, chunk_size)

    """__________消息相关__________"""

    # 给自己发送消息
    @staticmethod
    def send_msg_to_self(msg):
        # 在 Web 微信中把自己加为好友
        WxPyUtils.bot_instance.self.add()
        WxPyUtils.bot_instance.self.accept()
        # 发送消息给自己
        WxPyUtils.bot_instance.self.send(msg)

    # 发送文本给好友  friend_obj 是 find_friend() 得到的
    @staticmethod
    def send_txt_msg(friend_obj, msg):
        friend_obj.send(msg)

    # 发送图片
    @staticmethod
    def send_img_msg(friend_obj, img_path):
        friend_obj.send_image(img_path)

    # 以动态的方式发送图片
    @staticmethod
    def send_img_dynamic(friend_obj, img_path):
        friend_obj.send('@img@' + img_path)

    # 发送视频
    @staticmethod
    def send_video(friend_obj, video_path):
        friend_obj.send_video(video_path)

    # 发送文件
    @staticmethod
    def send_file(friend_obj, file_path):
        friend_obj.send_file(file_path)

    # 上传文件，并获取 media_id，可用于重复发送图片、表情、视频，和文件
    @staticmethod
    def upload_file(path):
        return WxPyUtils.bot_instance.upload_file(path)

    """__________操作__________"""

    # 加好友和建群
    # user – 用户对象或 user_name,verify_content – 验证说明信息
    @staticmethod
    def add_friend(user, verify_content=''):
        WxPyUtils.bot_instance.add_friend(user, verify_content)

    # 添加/关注 公众号
    # addr_obj:公众号对象
    @staticmethod
    def add_public_addr(addr_obj):
        WxPyUtils.bot_instance.add_mp(addr_obj)

    # 接受用户为好友
    @staticmethod
    def accept_friend(user, verify_content=''):
        WxPyUtils.bot_instance.accept_friend(user, verify_content)

    # 创建一个新的群聊
    # users – 用户列表 (不含自己，至少 2 位)
    # topic – 群名称
    # 若建群成功，返回一个新的群聊对象
    @staticmethod
    def create_group(users_list, topic=None):
        return WxPyUtils.bot_instance.create_group(users_list, topic)

# ---自动响应各类消息---
# 打印来自其他好友、群聊和公众号的消息
# 报错：module 'wxpy.api.bot' has no attribute 'register'


# 图灵机器人
tuling_friend = WxPyUtils.find_friend('铸剑师')
tuling = Tuling(api_key='f26b38ec8d8b44cfa8518116ddd7da24')


# @bot_instance.register()
# def print_others(msg):
#     print(msg)


# 回复 my_friend 的消息 (优先匹配后注册的函数!)
@WxPyUtils.bot_instance.register(tuling_friend)
def reply_my_friend(msg):
    tuling.do_reply(msg)


# 自动接受新的好友请求
# module 'wxpy.api.bot' has no attribute 'register'
# @bot_instance.register(msg_types=FRIENDS)
# def auto_accept_friends(msg):
#     # 接受好友请求
#     new_friend = msg.card.accept()
#     # 向新的好友发送消息
#     new_friend.send('哈哈，我自动接受了你的好友请求')


# 在完成注册操作后，若没有其他操作，程序会因主线程执行完成而退出。因此务必堵塞线程以保持监听状态！
# 所以使用 embed() 堵塞线程，并进入 Python 命令行
# wxpy.embed()
